#include <mcp/server/fastmcp.h>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <memory>

using namespace mcp;
using namespace mcp::server;
using namespace mcp::types;

// Simple addition tool
Result<json::Value> add_tool(const json::Value& args, Context<>& context) {
    auto a = args["a"].as_double();
    auto b = args["b"].as_double();
    auto result = a + b;

    context.info(std::format("Adding {} and {} = {}", a, b, result));

    return json::Value::object({
        {"result", result}
    });
}

// Greeting resource
Result<ResourceContent> greeting_resource(const std::string& uri, Context<>& context) {
    context.info(std::format("Accessing greeting resource: {}", uri));

    return ResourceContent{
        .contents = std::vector<std::shared_ptr<ContentBlock>>{
            std::make_shared<TextContent>(std::format("Hello from MCP! You requested: {}", uri))
        },
        .uri = uri
    };
}

// Math prompt
Result<std::vector<PromptMessage>> math_prompt(const json::Value& args, Context<>& context) {
    std::string operation = "addition";
    double a = 10.0;
    double b = 20.0;

    if (args.contains("operation")) {
        operation = args["operation"].as_string();
    }
    if (args.contains("a")) {
        a = args["a"].as_double();
    }
    if (args.contains("b")) {
        b = args["b"].as_double();
    }

    std::string problem;
    if (operation == "addition") {
        problem = std::format("What is {} + {}?", a, b);
    } else if (operation == "subtraction") {
        problem = std::format("What is {} - {}?", a, b);
    } else if (operation == "multiplication") {
        problem = std::format("What is {} × {}?", a, b);
    } else if (operation == "division") {
        problem = std::format("What is {} ÷ {}?", a, b);
    } else {
        problem = std::format("Solve for {} and {} with operation: {}", a, b, operation);
    }

    context.info(std::format("Generated math problem: {}", problem));

    return std::vector<PromptMessage>{
        PromptMessage{
            .role = PromptRole::User,
            .content = std::make_shared<TextContent>(problem)
        }
    };
}

int main() {
    try {
        std::cout << "MCP C++ Fast Server Example\n";
        std::cout << "============================\n\n";

        // Create server configuration
        ServerConfig config{
            .name = "MCP C++ Fast Server",
            .version = "1.0.0",
            .description = "Example MCP server demonstrating basic functionality",
            .debug = true,
            .host = "localhost",
            .port = 8080
        };

        // Create server
        auto server = std::make_shared<FastMCPServer>(config);

        // Register tools
        std::cout << "Registering tools...\n";

        ToolOptions add_options{
            .description = "Add two numbers",
            .input_schema = json::object_schema()
                .property("a", json::number_schema().description("First number"))
                .property("b", json::number_schema().description("Second number"))
                .required({"a", "b"})
        };

        server->tool("add", add_tool, add_options);

        // Register resources
        std::cout << "Registering resources...\n";

        ResourceOptions greeting_options{
            .name = "Greeting",
            .description = "Simple greeting resource",
            .mime_type = "text/plain"
        };

        server->resource("greeting://hello", greeting_resource, greeting_options);

        // Register prompts
        std::cout << "Registering prompts...\n";

        PromptOptions math_options{
            .description = "Generate math problems"
        };

        server->prompt("math", math_prompt, math_options);

        // List registered items
        std::cout << "\nRegistered tools:\n";
        for (const auto& tool : server->list_tools()) {
            std::cout << "  - " << tool.name << ": " << tool.description << "\n";
        }

        std::cout << "\nRegistered resources:\n";
        for (const auto& resource : server->list_resources()) {
            std::cout << "  - " << resource.uri << ": " << resource.name << "\n";
        }

        std::cout << "\nRegistered prompts:\n";
        for (const auto& prompt : server->list_prompts()) {
            std::cout << "  - " << prompt.name << ": " << prompt.description.value_or("No description") << "\n";
        }

        // Start server with stdio transport
        std::cout << "\nStarting server with stdio transport...\n";
        std::cout << "Press Ctrl+C to stop the server\n";

        server->run<mcp::transport::StdioTransport>();

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << "\n";
        return 1;
    }

    return 0;
}